package com.jcbase.core.util;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;

import com.jcbase.core.type.WeChatMenuEnum;
import com.jcbase.core.weixin.menu.Button;
import com.jcbase.core.weixin.menu.ClickButton;
import com.jcbase.core.weixin.menu.ViewButton;
import com.jcbase.core.weixin.template.DataItem2;
import com.jcbase.core.weixin.template.TempItem;
import com.jcbase.core.weixin.template.TempToJson;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.weixin.sdk.api.ApiConfig;
import com.jfinal.weixin.sdk.api.ApiResult;
import com.jfinal.weixin.sdk.api.TemplateMsgApi;

public class WeiXinUtils {

	/**
	 * 如果要支持多公众账号，只需要在此返回各个公众号对应的 ApiConfig 对象即可 可以通过在请求 url 中挂参数来动态从数据库中获取
	 * ApiConfig 属性值
	 */
	public static ApiConfig getApiConfig(String toUserName) {
		ApiConfig ac = new ApiConfig();
		if (CommonUtils.isEmpty(toUserName)) {//当不为空时
			// 配置微信 API 相关常量
			ac.setToken(PropKit.get("token"));
			ac.setAppId(PropKit.get("appId"));
			ac.setAppSecret(PropKit.get("appSecret"));

			/**
			 * 是否对消息进行加密，对应于微信平台的消息加解密方式： 1：true进行加密且必须配置 encodingAesKey
			 * 2：false采用明文模式，同时也支持混合模式
			 */
			ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
			ac.setEncodingAesKey(PropKit.get("encodingAesKey", PropKit.get("encodingAesKey")));
		}
		return ac;
	}

	public static String filterWeixinEmoji(String source) {
		if (containsEmoji(source)) {
			source = filterEmoji(source);
		}
		return source;
	}

	/**
	 * 检测是否有emoji字符
	 * 
	 * @param source
	 * @return 一旦含有就抛出
	 */
	public static boolean containsEmoji(String source) {
		if (StrKit.isBlank(source)) {
			return false;
		}

		int len = source.length();

		for (int i = 0; i < len; i++) {
			char codePoint = source.charAt(i);

			if (isEmojiCharacter(codePoint)) {
				// do nothing，判断到了这里表明，确认有表情字符
				return true;
			}
		}

		return false;
	}

	private static boolean isEmojiCharacter(char codePoint) {
		return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
				|| ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
				|| ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
	}

	/**
	 * 过滤emoji 或者 其他非文字类型的字符
	 * 
	 * @param source
	 * @return
	 */
	public static String filterEmoji(String source) {

		if (!containsEmoji(source)) {
			return source;// 如果不包含，直接返回
		}
		// 到这里铁定包含
		StringBuilder buf = null;

		int len = source.length();

		for (int i = 0; i < len; i++) {
			char codePoint = source.charAt(i);

			if (isEmojiCharacter(codePoint)) {
				if (buf == null) {
					buf = new StringBuilder(source.length());
				}

				buf.append(codePoint);
			} else {
			}
		}

		if (buf == null) {
			return source;// 如果没有找到 emoji表情，则返回源字符串
		} else {
			if (buf.length() == len) {// 这里的意义在于尽可能少的toString，因为会重新生成字符串
				buf = null;
				return source;
			} else {
				return buf.toString();
			}
		}
	}

	/** 
	 * emoji表情转换(hex -> utf-16) 
	 *  
	 * @param hexEmoji 
	 * @return 
	 */
	public static String emoji(int hexEmoji) {
		return String.valueOf(Character.toChars(hexEmoji));
	}

	/**
	 * @category 得到菜单按钮
	 * @param type
	 * @param name
	 * @param key
	 * @param url
	 * @return
	 */
	public static Button getButton(String type, String name, String key, String url) {
		if (StringUtils.isNotBlank(type)) {
			WeChatMenuEnum menuEnum = WeChatMenuEnum.valueOf(type);
			switch (menuEnum) {
			case view:
				ViewButton viewButton = new ViewButton();
				viewButton.setName(name);
				viewButton.setType(WeChatMenuEnum.view.name());
				viewButton.setUrl(url);
				return viewButton;
			case click:
				ClickButton clickButton = new ClickButton();
				clickButton.setName(name);
				clickButton.setKey(key);
				clickButton.setType(WeChatMenuEnum.click.name());
				return clickButton;
			case location_select:
				ClickButton locationSelectButton = new ClickButton();
				locationSelectButton.setName(name);
				locationSelectButton.setKey(key);
				locationSelectButton.setType(WeChatMenuEnum.location_select.name());
				return locationSelectButton;
			case pic_photo_or_album:
				ClickButton picThotoOrAlbumButton = new ClickButton();
				picThotoOrAlbumButton.setName(name);
				picThotoOrAlbumButton.setKey(key);
				picThotoOrAlbumButton.setType(WeChatMenuEnum.pic_photo_or_album.name());
				return picThotoOrAlbumButton;
			case pic_weixin:
				ClickButton picWeixinButton = new ClickButton();
				picWeixinButton.setName(name);
				picWeixinButton.setKey(key);
				picWeixinButton.setType(WeChatMenuEnum.pic_weixin.name());
				return picWeixinButton;
			case pic_sysphoto:
				ClickButton picSysphotoButton = new ClickButton();
				picSysphotoButton.setName(name);
				picSysphotoButton.setKey(key);
				picSysphotoButton.setType(WeChatMenuEnum.pic_sysphoto.name());
				return picSysphotoButton;
			case scancode_push:
				ClickButton scancodePushButton = new ClickButton();
				scancodePushButton.setName(name);
				scancodePushButton.setKey(key);
				scancodePushButton.setType(WeChatMenuEnum.scancode_push.name());
				return scancodePushButton;
			default:
				return null;
			}
		}
		return null;
	}

	/**
	 * 发送模板消息
	 * @param orderId
	 * @param price
	 * @param couresName
	 * @param teacherName
	 * @param openId
	 * @param url
	 * @return
	 */
	public static ApiResult sendTemplateMessage_2(String orderId, String price, String couresName, String teacherName,
			String openId, String url) {
		DataItem2 dataItem = new DataItem2();
		dataItem.setFirst(new TempItem("您好,你已购买课程成功", "#743A3A"));
		dataItem.setKeyword1(new TempItem(orderId, "#FF0000"));
		dataItem.setKeyword2(new TempItem(price + "元", "#c4c400"));
		dataItem.setKeyword3(new TempItem(couresName, "#c4c400"));
		dataItem.setKeyword4(new TempItem(teacherName, "#c4c400"));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日  HH时mm分ss秒");
		String time = sdf.format(new Date());
		dataItem.setKeyword5(new TempItem(time, "#0000FF"));
		dataItem.setRemark(new TempItem("\n 请点击详情直接看课程直播，祝生活愉快", "#008000"));

		String json = TempToJson.getTempJson(openId, "7y1wUbeiYFsUONKH1IppVi47WwViICAjREZSdR3Zahc", "#743A3A", url,
				dataItem);

		ApiResult result = TemplateMsgApi.send(json);
		return result;
	}

	public static ApiResult sendTemplateMessageByOpen(String orderId, String price, String couresName,
			String teacherName, String openId, String url) {
		DataItem2 dataItem = new DataItem2();
		dataItem.setFirst(new TempItem("您好,你已成功购买课程", "#000000"));
		dataItem.setKeyword1(new TempItem(orderId, "##000000"));
		dataItem.setKeyword2(new TempItem(price + "元", "#000000"));
		dataItem.setKeyword3(new TempItem(couresName, "#000000"));
		dataItem.setKeyword4(new TempItem(teacherName, "#000000"));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日  HH时mm分ss秒");
		String time = sdf.format(new Date());
		dataItem.setKeyword5(new TempItem(time + "\n我们的专业客服人员会在24小时内与您联系，请注意接听我们的电话，再次感谢您的支持！", "#000000"));
		dataItem.setRemark(new TempItem("\n请点击详情直接观看《大讲堂》课程直播，直播当天有效，祝生活愉快", "#008000"));

		String json = TempToJson.getTempJson(openId, "7y1wUbeiYFsUONKH1IppVi47WwViICAjREZSdR3Zahc", "#743A3A", url,
				dataItem);

		ApiResult result = TemplateMsgApi.send(json);
		return result;
	}

	public static ApiResult sendTemplateMessageByPrivate(String orderId, String price, String couresName,
			String teacherName, String openId, String url) {
		DataItem2 dataItem = new DataItem2();
		dataItem.setFirst(new TempItem("您好,你已成功购买课程", "#000000"));
		dataItem.setKeyword1(new TempItem(orderId, "##000000"));
		dataItem.setKeyword2(new TempItem(price + "元", "#000000"));
		dataItem.setKeyword3(new TempItem(couresName, "#000000"));
		dataItem.setKeyword4(new TempItem(teacherName, "#000000"));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日  HH时mm分ss秒");
		String time = sdf.format(new Date());
		dataItem.setKeyword5(new TempItem(time, "#000000"));
		dataItem.setRemark(new TempItem("\n我们的专业客服人员会在24小时内与您联系，请注意接听我们的电话，再次感谢您的支持！", "#008000"));

		String json = TempToJson.getTempJson(openId, "7y1wUbeiYFsUONKH1IppVi47WwViICAjREZSdR3Zahc", "#743A3A", url,
				dataItem);

		ApiResult result = TemplateMsgApi.send(json);
		return result;
	}

}